package im.rtx.core.utils; /**
 * Project  : JavaQQ
 * Package  : test
 * File     : util.Util.java
 * Author   : solosky < solosky772@qq.com >
 * Date     : 2009-10-8
 * Modified : 2009-10-8
 * License  : Apache License 2.0 
 */

import java.util.Random;
import java.util.StringTokenizer;

/**
 * 工具类，提供一些方便的方法，有些主要是用于调试用途，有些不是
 *
 * @author luma
 * @author notXX
 */
public class Util {

    // 随机类
    private static Random random;

    // 16进制字符数组
    private static char[] hex = new char[]{
            '0', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
    };
    // string buffer
    private static StringBuilder sb = new StringBuilder();

    /**
     * 把字节数组从offset开始的len个字节转换成一个unsigned int， 因为java里面没有unsigned，所以unsigned
     * int使用long表示的， 如果len大于8，则认为len等于8。如果len小于8，则高位填0 <br>
     * (edited by notxx) 改变了算法, 性能稍微好一点. 在我的机器上测试10000次, 原始算法花费18s, 这个算法花费12s.
     *
     * @param in     字节数组.
     * @param offset 从哪里开始转换.
     * @param len    转换长度, 如果len超过8则忽略后面的
     * @return
     */
    public static long getUnsignedInt(byte[] in, int offset, int len) {
        long ret = 0;
        int end = 0;
        if (len > 8)
            end = offset + 8;
        else
            end = offset + len;
        for (int i = offset; i < end; i++) {
            ret <<= 8;
            ret |= in[i] & 0xff;
        }
        return (ret & 0xffffffffl) | (ret >>> 32);
    }

    /**
     * 在buf字节数组中的begin位置开始，查找字节b出现的第一个位置
     *
     * @param buf   字节数组
     * @param begin 开始未知索引
     * @param b     要查找的字节
     * @return 找到则返回索引，否则返回-1
     */
    public static int indexOf(byte[] buf, int begin, byte b) {
        for (int i = begin; i < buf.length; i++) {
            if (buf[i] == b)
                return i;
        }
        return -1;
    }

    /**
     * 在buf字节数组中的begin位置开始，查找字节数组b中只要任何一个出现的第一个位置
     *
     * @param buf   字节数组
     * @param begin 开始未知索引
     * @param b     要查找的字节数组
     * @return 找到则返回索引，否则返回-1
     */
    public static int indexOf(byte[] buf, int begin, byte[] b) {
        for (int i = begin; i < buf.length; i++) {
            for (int j = 0; j < b.length; j++)
                if (buf[i] == b[j])
                    return i;
        }
        return -1;
    }

    /**
     * @return Random对象
     */
    public static Random random() {
        if (random == null)
            random = new Random();
        return random;
    }

    /**
     * @return 一个随机产生的密钥字节数组
     */
    public static byte[] randomKey() {
        byte[] key = new byte[16];
        random().nextBytes(key);
        return key;
    }


    /**
     * 返回unicode, 便于传输
     *
     * @param str
     * @return
     */
    public static byte[] unicode(String str) {
        byte[] unicode = new byte[str.length() * 2];
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            unicode[i * 2] = (byte) (0xFF & c);
            unicode[i * 2 + 1] = (byte) (0xFF & (c >> 8));
        }
        return unicode;
    }

    /**
     * 从content的offset位置起的4个字节解析成int类型
     *
     * @param content 字节数组
     * @param offset  偏移
     * @return int
     */
    public static final int parseInt(byte[] content, int offset) {
        return ((content[offset++] & 0xff) << 24) | ((content[offset++] & 0xff) << 16) | ((content[offset++] & 0xff) << 8) | (content[offset++] & 0xff);
    }

    /**
     * 从content的offset位置起的2个字节解析成char类型
     *
     * @param content 字节数组
     * @param offset  偏移
     * @return char
     */
    public static final char parseChar(byte[] content, int offset) {
        return (char) (((content[offset++] & 0xff) << 8) | (content[offset++] & 0xff));
    }

    /**
     * 把字节数组转换成16进制字符串
     *
     * @param b 字节数组
     * @return 16进制字符串，每个字节之间空格分隔，头尾无空格
     */
    public static String convertByteToHexString(byte[] b) {
        if (b == null)
            return "null";
        else
            return convertByteToHexString(b, 0, b.length);
    }

    /**
     * 把字节数组转换成16进制字符串
     *
     * @param b      字节数组
     * @param offset 从哪里开始转换
     * @param len    转换的长度
     * @return 16进制字符串，每个字节之间空格分隔，头尾无空格
     */
    public static String convertByteToHexString(byte[] b, int offset, int len) {
        if (b == null)
            return "null";

        // 检查索引范围
        int end = offset + len;
        if (end > b.length)
            end = b.length;

        sb.delete(0, sb.length());
        for (int i = offset; i < end; i++) {
            sb.append(hex[(b[i] & 0xF0) >>> 4])
                    .append(hex[b[i] & 0xF])
                    .append(' ');
        }
        if (sb.length() > 0)
            sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    /**
     * 把字节数组转换成16进制字符串
     *
     * @param b 字节数组
     * @return 16进制字符串，每个字节没有空格分隔
     */
    public static String convertByteToHexStringWithoutSpace(byte[] b) {
        if (b == null)
            return "null";

        return convertByteToHexStringWithoutSpace(b, 0, b.length);
    }

    /**
     * 把字节数组转换成16进制字符串
     *
     * @param b      字节数组
     * @param offset 从哪里开始转换
     * @param len    转换的长度
     * @return 16进制字符串，每个字节没有空格分隔
     */
    public static String convertByteToHexStringWithoutSpace(byte[] b, int offset, int len) {
        if (b == null)
            return "null";

        // 检查索引范围
        int end = offset + len;
        if (end > b.length)
            end = b.length;

        sb.delete(0, sb.length());
        for (int i = offset; i < end; i++) {
            sb.append(hex[(b[i] & 0xF0) >>> 4])
                    .append(hex[b[i] & 0xF]);
        }
        return sb.toString();
    }

    /**
     * 转换16进制字符串为字节数组
     *
     * @param s 16进制字符串，每个字节由空格分隔
     * @return 字节数组，如果出错，返回null，如果是空字符串，也返回null
     */
    public static byte[] convertHexStringToByte(String s) {
        try {
            s = s.trim();
            StringTokenizer st = new StringTokenizer(s, " ");
            byte[] ret = new byte[st.countTokens()];
            for (int i = 0; st.hasMoreTokens(); i++) {
                String byteString = st.nextToken();

                // 一个字节是2个16进制数，如果不对，返回null
                if (byteString.length() > 2)
                    return null;

                ret[i] = (byte) (Integer.parseInt(byteString, 16) & 0xFF);
            }
            return ret;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 把一个16进制字符串转换为字节数组，字符串没有空格，所以每两个字符
     * 一个字节
     *
     * @param s
     * @return
     */
    public static byte[] convertHexStringToByteNoSpace(String s) {
        int len = s.length();
        byte[] ret = new byte[len >>> 1];
        for (int i = 0; i <= len - 2; i += 2) {
            ret[i >>> 1] = (byte) (Integer.parseInt(s.substring(i, i + 2).trim(), 16) & 0xFF);
        }
        return ret;
    }
}
